<template xmlns="http://www.w3.org/1999/html">
  <div class="min-h-full w-full overflow-x-hidden p-4 px-6">
    <h1 class="mb-4 text-2xl font-bold">小决定</h1>
    <a-tabs v-model:activeKey="activeKey" size="large">
      <a-tab-pane tab="选项" key="0">
        <a-form>
          <a-form-item v-for="(option, index) in options" :key="index">
            <a-space>
              <a-button>{{ index + 1 }}</a-button>
              <a-space-compact class="site-space-compact-wrapper" block>
                <a-input
                  placeholder="添加一个选项吧"
                  v-model:value="option.name"
                >
                  <template #prefix>
                    <NotificationOutlined />
                  </template>
                </a-input>
                <a-input
                  placeholder="权重：自动"
                  v-model:value="option.weight"
                  suffix="%"
                >
                  <template #prefix>
                    <BarsOutlined />
                  </template>
                </a-input>
              </a-space-compact>
              <a-button
                class="flex items-center justify-center"
                type="dashed"
                danger
                @click="removeOption(option)"
              >
                <DeleteOutlined />
              </a-button>
            </a-space>
          </a-form-item>
          <a-form-item>
            <a-button
              type="dashed"
              block
              class="flex items-center justify-center"
              @click="addOption"
            >
              <PlusOutlined />
              添加选项
            </a-button>
          </a-form-item>
        </a-form>
        <a-divider />
        <a-button type="primary" class="w-full" size="large" @click="random"
          >决定!
        </a-button>
      </a-tab-pane>
      <a-tab-pane tab="转盘" key="1">
        <div class="mb-4 flex items-center justify-center">
          <span class="text-2xl font-medium">决定结果为：</span>
          <span class="text-2xl font-bold">123</span>
        </div>

        <canvas ref="wheel" width="300" height="300" class="mx-auto"></canvas>
        <div class="mt-4 flex w-full justify-center gap-8">
          <a-button type="primary" @click="" size="large"> 开始转盘 </a-button>
          <a-button @click="activeKey = '0'" size="large">返回</a-button>
          <a-button type="dashed" @click="copyToClipboard('111')" size="large">
            复制结果
          </a-button>
        </div>
      </a-tab-pane>
    </a-tabs>
    <!--    <a-modal v-model:open="showWheel" width="max-content" getContainer="">-->
    <!--      <template #title>随机转盘</template>-->
    <!--      <template #footer> </template>-->
    <!--    </a-modal>-->
  </div>
</template>
<script setup lang="ts">
import { message } from 'ant-design-vue'
import {
  DeleteOutlined,
  PlusOutlined,
  NotificationOutlined,
  BarsOutlined,
} from '@ant-design/icons-vue'
import { nextTick, ref } from 'vue'

interface OptionType {
  name: string
  index: number
  weight?: number
}

let activeKey = ref<string>('0')
let options = ref<OptionType[]>([
  {
    name: '吃饭',
    index: 0,
  },
  {
    name: '睡觉',
    index: 1,
  },
  {
    name: '写作业',
    index: 2,
  },
  {
    name: '写代码',
    index: 3,
  },
  {
    name: '运动',
    index: 4,
  },
])
const wheel = ref<HTMLCanvasElement>()
// let showWheel = ref<boolean>(false)

// 表单函数
function addOption() {
  options.value.push({
    name: '',
    index: options.value.length + 1,
  })
}

function resetOptions() {
  options.value = []
}

function removeOption(option: OptionType) {
  options.value = options.value.filter((item) => item.index !== option.index)
}

function getRandom(min: number, max: number) {
  return Math.floor(Math.random() * (max - min)) + min
}

// 转盘函数
function random() {
  activeKey.value = '1'
  nextTick(() => {
    drawWheel(options.value)
  })
}

function copyToClipboard(text: string) {
  navigator.clipboard.writeText(text)
  message.success(`复制成功：${text}`)
}

function drawWheel(options: OptionType[]) {
  const colors = [
    '#F87171', // red-400
    '#FB923C', // orange-400
    '#FBBF24', // amber-400
    '#FACC15', // yellow-400
    '#4ADE80', // green-400
    '#34D399', // emerald-400
    '#38BDF8', // sky-400
    '#60A5FA', // blue-400
    '#818CF8', // indigo-400
    '#A78BFA', // violet-400
    '#E879F9', // fuchsia-400
    '#F472B6', // pink-400
  ]
  const WheelWidth = wheel.value?.width || 500,
    WheelHeight = wheel.value?.height || 500,
    centerX = WheelWidth / 2,
    centerY = WheelHeight / 2
  // 让 canvas 变高清
  const makeCanvasHD = (
    canvas: HTMLCanvasElement,
    cssW: number,
    cssH: number,
    ratio = window.devicePixelRatio || 1,
  ) => {
    canvas.width = cssW * ratio
    canvas.height = cssH * ratio

    canvas.style.width = cssW + 'px'
    canvas.style.height = cssH + 'px'

    const ctx = canvas.getContext('2d')!
    ctx.setTransform(ratio, 0, 0, ratio, 0, 0)
    return ctx
  }
  const canvas = wheel.value
  if (!canvas) {
    message.error('生成转盘时发生了未知错误')
    return
  }

  const ctx = makeCanvasHD(canvas, WheelWidth, WheelHeight)

  ctx.clearRect(0, 0, WheelWidth, WheelHeight)
  ctx.save()
  ctx.shadowColor = 'rgba(0,0,0,0.25)'
  ctx.shadowBlur = 12
  ctx.beginPath()
  ctx.moveTo(centerX, centerY)
  ctx.arc(centerX, centerY, 240, 0, Math.PI * 2)
  ctx.fillStyle = '#FFFFFF'
  ctx.fill()
  ctx.closePath()
  ctx.restore()
  let angleCnt = -Math.PI / 2
  const pickColor = (idx: number, total: number) => {
    if (total === 1) return colors[0]
    const step = colors.length / total
    const offset = Math.floor(step / 2)
    const colorIdx = Math.floor((idx * step + offset) % colors.length)
    return colors[colorIdx]
  }
  const drawSlice = (index: number, weight: number, name: string) => {
    let angle = (weight / 100) * 2 * Math.PI
    ctx.beginPath()
    ctx.moveTo(centerX, centerY)
    ctx.arc(centerX, centerY, 80, angleCnt, angleCnt + angle)
    ctx.arc(centerX, centerY, 200, angleCnt + angle, angleCnt, true)
    //
    ctx.fillStyle = pickColor(index + 1, options.length)
    ctx.fill()
    ctx.lineTo(centerX, centerY)
    ctx.strokeStyle = '#fff'
    ctx.lineWidth = 4
    ctx.stroke()
    const textAngle = angleCnt + angle / 2
    const textX = centerX + Math.cos(textAngle) * 140
    const textY = centerY + Math.sin(textAngle) * 140

    ctx.save()
    ctx.translate(textX, textY)
    ctx.rotate(textAngle + Math.PI / 2)
    ctx.fillStyle = '#fff'
    ctx.font = '18px sans-serif'
    ctx.textAlign = 'center'
    ctx.textBaseline = 'middle'
    ctx.fillText(name, 0, 0)
    ctx.restore()
    ctx.closePath()
    angleCnt += angle
  }
  // 渲染半圆
  let cnt = 0
  const weightSum = options.reduce((acc, item) => {
    cnt += item.weight ? 0 : 1
    return acc + (item.weight ? item.weight : 0)
  }, 0)
  cnt = cnt === 0 ? 1 : cnt
  const sliceWeight = (100 - weightSum) / cnt
  console.log(sliceWeight)
  for (let item of options) {
    drawSlice(
      item.index - 1,
      item.weight ? item.weight : sliceWeight,
      item.name,
    )
  }
  // 中心小圆
  ctx.save()

  ctx.beginPath()
  ctx.shadowColor = 'rgba(0,0,0,0.25)'
  ctx.shadowBlur = 12
  ctx.moveTo(centerX, centerY)
  ctx.arc(centerX, centerY, 30, 0, Math.PI)
  ctx.lineTo(centerX, centerY - 60)
  ctx.lineTo(centerX + 30, centerY)
  ctx.fillStyle = '#ec3535'
  ctx.fill()
  ctx.closePath()

  ctx.beginPath()
  ctx.moveTo(centerX, centerY)
  ctx.arc(centerX, centerY, 30, 0, Math.PI * 2)
  ctx.fillStyle = '#ffffff'
  ctx.fill()
  ctx.closePath()
  ctx.restore()
}
</script>
<style scoped></style>
